
#include "ESP8266.h"
#include "cJSON.h"

#include "delay.h"
#include "usart.h"

#define ESP8266_WIFI_INFO "AT+CWJAP=\"Bluetooth\",\"218349@w\"\r\n"
#define MQTTUSERCFG "AT+MQTTUSERCFG=0,1,\"NULL\",\"ESP_DEV&k0brbe2WP8y\",\"db4f48e66fa1e0056b8c341f1daf38c9c1184af0e371d729cae60cb179a5947e\",0,0,\" \"\r\n"
#define MQTTCLIENTID "AT+MQTTCLIENTID=0,\"k0brbe2WP8y.ESP_DEV|securemode=2\\,signmethod=hmacsha256\\,timestamp=1712744016449|\"\r\n"
#define MQTTCONN "AT+MQTTCONN=0,\"iot-06z00gck7vwvunr.mqtt.iothub.aliyuncs.com\",1883,1\r\n"
#define TOPIC_SET "AT+MQTTSUB=0,\"/sys/k0brbe2WP8y/ESP_DEV/thing/service/property/set\",1\r\n"

const char *settopic = "/sys/k0brbe2WP8y/ESP_DEV/thing/service/property/set";
const char *pubtopic = "/sys/k0brbe2WP8y/ESP_DEV/thing/event/property/post";
const char *subtopic = "/sys/k0brbe2WP8y/ESP_DEV/thing/event/property/post_reply";

const char *func1 = "temperature";
const char *func2 = "humidity";
const char *func3 = "WorkTime";
const char *func4 = "PowerSwitch";

char ESP8266_RX_BUFF[ESP8266_RX_BUFF_SIZE];
unsigned short ESP8266_RX_STA;
unsigned short ESP8266_RX_STAPRE;

void ESP8266_Init(void)
{
	ESP8266_Clear(); // 清空接收缓冲
// UsartPrintf(USART_DEBUG, "1.AT");
// while (ESP8266_SendCmd("AT+RST\r\n", "OK", 100))
// {
// }
// delay_ms(500);
#if DEBUG
	UsartPrintf(USART_DEBUG, "AT");
#endif
	while (ESP8266_SendCmd("AT\r\n", "OK", 100))
	{
	}
	delay_ms(500);
#if DEBUG
	UsartPrintf(USART_DEBUG, "AT+RST");
#endif
	while (ESP8266_SendCmd("AT+RST\r\n", "ready", 100))
	{
	}
	delay_ms(500);
#if DEBUG
	UsartPrintf(USART_DEBUG, "AT+CWMODE=1\r\n");
#endif
	while (ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK", 100))
	{
	}
	delay_ms(500);
#if DEBUG
	UsartPrintf(USART_DEBUG, "AT+CWDHCP=1,1\r\n");
#endif
	while (ESP8266_SendCmd("AT+CWDHCP=1,1\r\n", "OK", 100))
	{
	}
	delay_ms(500);
#if DEBUG
	UsartPrintf(USART_DEBUG, "ESP8266_WIFI_INFO\r\n");
#endif
	while (ESP8266_SendCmd(ESP8266_WIFI_INFO, "GOT IP", 500))
	{
	}
	delay_ms(500);
#if DEBUG
	UsartPrintf(USART_DEBUG, "AT+CIPSNTPCFG\r\n");
#endif
	while (ESP8266_SendCmd("AT+CIPSNTPCFG=1,8,\"ntp1.aliyun.com\"\r\n", "OK", 100))
	{
	}
	delay_ms(500);
#if DEBUG
	UsartPrintf(USART_DEBUG, "ESP8266 Init OK\r\n");
#endif
	MQTT_Init();
}
void MQTT_Init(void)
{
#if DEBUG
	UsartPrintf(USART_DEBUG, "AT+MQTTUSERCFG\r\n");
#endif
	while (ESP8266_SendCmd(MQTTUSERCFG, "OK", 200))
	{
	}
	delay_ms(500);
#if DEBUG
	UsartPrintf(USART_DEBUG, "AT+MQTTCLIENTID\r\n");
#endif
	while (ESP8266_SendCmd(MQTTCLIENTID, "OK", 200))
	{
	}
	delay_ms(500);
	// while (ESP8266_SendCmd("k0brbe2WP8y.ESP_DEV|securemode=2,signmethod=hmacsha256,timestamp=1712735861337|", "OK", 200))
	// {
	// }
	// delay_ms(500);
#if DEBUG
	UsartPrintf(USART_DEBUG, "AT+MQTTCONN\r\n");
#endif
	while (ESP8266_SendCmd(MQTTCONN, "OK", 200))
	{
	}
	delay_ms(500);
#if DEBUG
	UsartPrintf(USART_DEBUG, "AT+TOPIC_SET\r\n");
#endif
	while (ESP8266_SendCmd(TOPIC_SET, "OK", 200))
	{
	}
	delay_ms(500);
#if DEBUG
	UsartPrintf(USART_DEBUG, "MQTT Init OK\r\n");
#endif
}

void ESP8266_Clear(void)
{
	memset(ESP8266_RX_BUFF, 0, sizeof(ESP8266_RX_BUFF));
	ESP8266_RX_STA = 0;
	ESP8266_RX_STAPRE = -1;
}

/// @brief
/// @param
/// @return ESP8266_RX_STA=0返回没有接收，ESP8266_RX_STA == ESP8266_RX_STAPR前后接收一致成功接收
bool ESP8266_WaitRecive(void)
{
	if (ESP8266_RX_STA == 0)
		return false;
	if (ESP8266_RX_STA == ESP8266_RX_STAPRE)
	{
		ESP8266_RX_STA = 0;
		return true;
	}
	ESP8266_RX_STAPRE = ESP8266_RX_STA;
	return false;
}
/// @brief
/// @param cmd
/// @param res 回复的关键字
/// @return 发送成功并回复了返回false  发送没有回复了返回true
bool ESP8266_SendCmd(char *cmd, char *res, u32 Timeout)
{

	// UsartPrintf(USART3, "%s", cmd);
	USARTx_SendString(USART3, (u8 *)cmd, strlen(cmd)); // 发送命令
	while (Timeout--)
	{
		if (ESP8266_WaitRecive())
		{
#if DEBUG
			UsartPrintf(USART_DEBUG, "%s", ESP8266_RX_BUFF);
#endif
			if (Timeout > 0 && strstr(ESP8266_RX_BUFF, res) != NULL)
			{
				ESP8266_Clear(); // 清空接收缓冲
				return false;
			}
		}
		delay_ms(20);
	}
	return true;
}

// AT+MQTTPUB=0,"/sys/k0brbe2WP8y/ESP_DEV/thing/event/property/post","{\"params\":{\"temperature\":25,\"humidity\":50,\"PowerSwitch\":1}}",1,0
//  +MQTTSUBRECV:0,"/sys/k0brbe2WP8y/ESP_DEV/thing/event/property/post_reply",107,{"code":200,"data":{},
//	"id":"null","message":"success","method":"thing.event.property.post","version":"1.0"}

/// @param
/// @return 发送数据到云端成功返回false 失败返回true
bool ESP8266_SendData(void)
{
	u32 Timeout = 100;																																											// 超时等待回复
	UsartPrintf(USART3, "AT+MQTTPUB=0,\"%s\",\"{\\\"params\\\":{\\\"%s\\\":%d\\,\\\"%s\\\":%d\\,\\\"%s\\\":%d}}\",1,0\r\n", pubtopic, func1, Temperature, func2, Humidity, func4, PowerSwitch); // 发送数据
	while (Timeout--)
	{
		if (ESP8266_WaitRecive())
		{
#if DEBUG
			UsartPrintf(USART_DEBUG, "%s\r\n", ESP8266_RX_BUFF);
#endif
			if (Timeout > 0 && strstr(ESP8266_RX_BUFF, "thing.event.property.post") != NULL)
			{
				delay_ms(500);
				ESP8266_Clear(); // 清空接收缓冲
				return false;
			}
		}
		delay_ms(5);
	}
	return true;
}

// +MQTTSUBRECV:0,"/sys/k0brbe2WP8y/ESP_DEV/thing/service/property/set",240,{"deviceType":"CustomCategory",
//		"iotId":"A8Ot9w1EhFtCj6shNV8bk0brb0","requestId":"null","checkFailedData":{},"productKey":"k0brbe2WP8y",
//		"gmtCreate":1712749141158,"deviceName":"APP_DEV","items":{"WorkTime":{"time":1712749141147,"value":240}}}

// +MQTTSUBRECV:0,"/sys/k0brbe2WP8y/ESP_DEV/thing/service/property/set",241,{"deviceType":"CustomCategory",
//		"iotId":"A8Ot9w1EhFtCj6shNV8bk0brb0","requestId":"null","checkFailedData":{},"productKey":"k0brbe2WP8y",
//		"gmtCreate":1712749168343,"deviceName":"APP_DEV","items":{"PowerSwitch":{"time":1712749168338,"value":0}}}

/// @brief 接收到云端的消息处理
/// @param
void CommandAnalyse(void)
{
	int i = 0;
	u32 Timeout = 5;
	cJSON *root = NULL;
	cJSON *item = NULL;
#if DEBUG
	UsartPrintf(USART_DEBUG, "%s\r\n", ESP8266_RX_BUFF);
#endif
	while (Timeout--)
	{
		while (ESP8266_RX_BUFF[i++] != '\0')
		{
			if (strncmp((ESP8266_RX_BUFF + i), "items", 5) == 0)
			{
				while (ESP8266_RX_BUFF[i++] != ':')
					;
				root = cJSON_Parse(ESP8266_RX_BUFF + i);
				if (strstr(ESP8266_RX_BUFF + i, "WorkTime") != NULL)
				{
					item = cJSON_GetObjectItem(root, "WorkTime");
					WorkTime = cJSON_GetObjectItem(item, "value")->valueint;
				}
				if (strstr(ESP8266_RX_BUFF + i, "PowerSwitch") != NULL)
				{
					// item = cJSON_GetObjectItem(root, "PowerSwitch");
					// PowerSwitch = cJSON_GetObjectItem(item, "value")->valueint;
					PowerSwitch = 1;
				}
#if DEBUG
				UsartPrintf(USART_DEBUG, "WorkTime=%d,PowerSwitch=%d\r\n", WorkTime, PowerSwitch);
#endif
				ESP8266_Clear(); // 清空接收缓冲
				delay_ms(20);
				goto out;
			}
		}
	}
out:
	return;
}

#if ESP8266_RX_ENABLE
void USART3_IRQHandler(void)
{
	if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
	{
		ESP8266_RX_BUFF[ESP8266_RX_STA++] = USART_ReceiveData(USART3);
		if (ESP8266_RX_STA >= ESP8266_RX_BUFF_SIZE)
		{
			ESP8266_RX_BUFF[ESP8266_RX_STA - 1] = '\0';
			// UsartPrintf(USART_DEBUG, "%s", ESP8266_RX_BUFF);
			// 			if (strstr(ESP8266_RX_BUFF, "/sys/k0brbe2WP8y/ESP_DEV/thing/service/property/set") != NULL)
			// 			{
			// #if DEBUG
			// 				UsartPrintf(USART_DEBUG, "CommandAnalyse\r\n");
			// #endif
			// 				CommandAnalyse();
			// 			}
		}
		USART_ClearFlag(USART3, USART_FLAG_RXNE);
	}
}
#endif
